#pragma once

#include <QObject>
#include <QString>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <memory>
#include "kernel/interfaces/ILogger.h"

namespace application {

// Forward declaration
namespace area { class AreaManager; }
namespace lift { class LiftManager; }

namespace third_area {

/**
 * @brief 第三方阻塞区域
 * @details 管理与第三方车辆(如叉车)共享的区域，提供互斥访问控制
 */
class ThirdBlockArea : public QObject {
    Q_OBJECT

public:
    explicit ThirdBlockArea(const QString& areaId, int floor,
                           std::shared_ptr<kernel::ILogger> logger = nullptr,
                           QObject* parent = nullptr);
    ~ThirdBlockArea() = default;

    /**
     * @brief 获取区域ID
     */
    QString getAreaId() const { return m_areaId; }

    /**
     * @brief 获取楼层
     */
    int getFloor() const { return m_floor; }

    /**
     * @brief 检查区域是否被占用
     */
    bool isOccupied() const { return m_isOccupied; }
    bool isPreOccupied() const { return m_preOccupyAgvId != -1 && m_currentOccupyAgvId == -1; }
    bool isAgvOccupied() const { return m_currentOccupyAgvId != -1; }
    int getPreOccupyAgvId() const { return m_preOccupyAgvId; }
    int getCurrentOccupyAgvId() const { return m_currentOccupyAgvId; }
    QString getThirdPartyVehicleId() const { return m_thirdPartyId; }

    /**
     * @brief AGV预占用区域
     */
    void preOccupy(int agvId);

    /**
     * @brief AGV尝试占用区域（含预占逻辑）
     * @return true 表示成功占用或已被当前AGV占用；false 表示被第三方/其他AGV占用
     */
    bool tryAgvAcquire(int agvId);

    /**
     * @brief 第三方车辆占用区域
     * @return true表示占用成功，false表示失败
     */
    bool thirdPartyOccupy(const QString& vehicleId);

    /**
     * @brief 检查是否被第三方车辆占用
     */
    bool isThirdPartyOccupied(int agvId);

    /**
     * @brief AGV取消占用
     */
    void cancelOccupy(int agvId);

    /**
     * @brief 第三方车辆取消占用
     */
    void cancelOccupy(const QString& vehicleId);

    /**
     * @brief 强制解除占用
     */
    void forceRelease();

    /**
     * @brief 关联地图区域管理器
     */
    void linkAreaManager(area::AreaManager* areaManager);

    /**
     * @brief 发送POST请求到第三方系统
     */
    void sendPostRequest();

    /**
     * @brief 配置与电梯共享的锁资源（可选）
     */
    void configureLiftLockResource(int liftNum, std::weak_ptr<lift::LiftManager> liftManager);

    /**
     * @brief 请求占用共享电梯锁
     */
    bool acquireLiftLock(const QString& ownerId);

    /**
     * @brief 释放共享电梯锁
     */
    void releaseLiftLock(const QString& ownerId);

private slots:
    void slot_enterArea(int agvId);
    void slot_exitArea(int agvId);
    void slot_onAreaEntered(const QString& areaId, int agvId);
    void slot_onAreaExited(const QString& areaId, int agvId);
    void requestFinished(QNetworkReply* reply);

private:
    QString m_areaId;
    int m_floor;
    bool m_isOccupied = false;
    int m_currentOccupyAgvId = -1;
    int m_preOccupyAgvId = -1;
    QString m_thirdPartyId;  // 第三方车辆ID
    area::AreaManager* m_areaManager = nullptr;
    QNetworkAccessManager* m_httpMgr = nullptr;
    std::shared_ptr<kernel::ILogger> m_logger;
    int m_liftNum = 0;
    std::weak_ptr<lift::LiftManager> m_liftManager;
    QString m_liftLockOwner;
    bool m_areaManagerLinked{false};

    void forceReleaseLiftLock();
};

} // namespace third_area
} // namespace application
